package com.my.thread.syncRetuen;

import com.alibaba.fastjson.JSON;
import com.my.thread.syncRetuen.service.SpringThreadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author timo 2021/3/18
 */
@RestController
@Slf4j
public class SpringTestController {
    @Autowired
    private SpringThreadService serviceImpl;

    //使用自旋操作，等待任务结果返回。
    @RequestMapping("/helloFuture")
    @ResponseBody
    public String helloFuture() {
        //线程安全的 可见性 原子性
        AtomicInteger integer = new AtomicInteger();
        integer.set(12);

        try {
            Future<String> future1 = serviceImpl.doTask1();
            Future<String> future2 = serviceImpl.doTask2();
            //自旋锁，停止等待
            while (true) {
                if (future1.isDone() && future2.isDone()) {
                    log.info("Task1 result:{}", future1.get());
                    log.info("Task2 result:{}", future2.get());
                    break;
                }
                Thread.sleep(1000);
            }
            log.info("All tasks finished.");
            return "S";
        } catch (InterruptedException e) {
            log.error("错误信息1", e);
            return "F";
        } catch (ExecutionException e) {
            log.error("错误信息2", e);
            return "F";
        }
    }
    //使用CountDownLatch计数器
    @RequestMapping("/helloFuture2")
    @ResponseBody
    public String helloFuture2() {
        try {
            CountDownLatch latch=new CountDownLatch(2);
            Future<String> future1 = serviceImpl.doTask1(latch);
            Future<String> future2 = serviceImpl.doTask2(latch);
            //等待两个线程执行完毕
            latch.await();
            log.info("All tasks finished!");
            String result1 = future1.get();
            String result2 = future2.get();
            log.info(result1+"--"+result2);
            return "S";
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return "F";
    }
    /*使用Future的get方法的阻塞特性*/
    @RequestMapping("/helloFuture3")
    @ResponseBody
    public String helloFuture3() {
        try {
            List<Future<String>> tasks = new ArrayList<>();
            List<String> results = new ArrayList<>();
            tasks.add(serviceImpl.doTask1());
            tasks.add(serviceImpl.doTask2());
            //各个任务执行完毕
            for (Future<String> task : tasks) {
                //每个任务都会再在此阻塞。
                results.add(task.get());
            }
            log.info("All tasks finished!");
            log.info("执行结果：{}", JSON.toJSONString(results));
            return "S";
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return "F";
    }
}
